import log from '@/utils/log'
import responseJson, { sendMessageToWeb } from '@/bot/common/response'
import { createSelfMessageDetail } from '@/bot/common'
import { getConfig } from '@/utils/file'
import AiModel from '@/bot/ai-model'

// 加载模型
const ai = new AiModel()

/**
 * @Author: lcq
 * @Date: 2025-01-01 14:56:50
 * @brief: 消息回复
 * @param {*} msg
 * @return {*}
 */
export async function msgReply(msg) {
  const {
    autoReply = false, // 是否开启自动回复
    modelApi = '', // AI平台名称
    model: AiModelName = '', // AI模型名称
    apiKey = '', // AI模型API Key
    responseDelayTime = 0, // AI回复延迟多少时间发生提示语
    responseDelay = '', // AI回复延迟提示语
    roleSetting = '', // AI模型角色设定
    whitelist: aliasWhiteList = [], // 从配置文件中导入联系人白名单
    groupWhitelist: roomWhiteList = [], // 从配置文件中导入群聊白名单
    msgPrefix: autoReplyPrefix = [] // 从配置文件中导入需要自动回复的消息前缀，默认配空串或不配置则等于无前缀
  } = await getConfig('ai')

  if (!autoReply) {
    log.debug('未开启自动回复')
    return // 如果未开启自动回复则不处理
  } else {
    log.debug('已开启自动回复', 'AiModel:' + JSON.stringify({ modelApi, AiModelName }))
  }

  const { bot } = global // 机器人实例

  const chatId = msg.payload.listenerId || msg.payload.roomId // 消息ID
  const contactSelf = bot.currentUser // 机器人自己
  const botName = '@' + contactSelf.name() // 机器人名称
  const contact = msg.talker() // 发消息人

  // eslint-disable-next-line no-unused-vars
  const receiver = msg.to() // 消息接收人，群聊时为群聊对象，单聊时为对方

  const content = msg.text() // 消息内容
  const room = msg.room() // 是否是群消息
  const roomName = (await room?.topic()) || null // 群名称
  const remarkName = await contact.alias() // 备注名称
  const name = await contact.name() // 微信名称
  const isText = msg.type() === bot.Message.Type.Text // 消息类型是否为文本
  const isRoom = roomWhiteList.includes(roomName) && content.includes(`${botName}`) // 是否在群聊白名单内并且艾特了机器人
  const isAlias = aliasWhiteList.includes(remarkName) || aliasWhiteList.includes(name) // 发消息的人是否在联系人白名单内
  const isBotSelf = botName === `@${remarkName}` || botName === `@${name}` // 是否是机器人自己
  const isOfficial = contact.type() === bot.Contact.Type.Official // 是否是公众号
  if (isBotSelf || !isText || isOfficial) return // 如果是机器人自己发送的消息或者消息类型不是文本则不处理

  try {
    // 消息是否带有自动回复前缀 或是 是否有前缀
    const isPrefix =
      !autoReplyPrefix?.length ||
      autoReplyPrefix.some((prefix) =>
        content.replace(`${botName}`, '').trimStart().startsWith(prefix)
      )
    const delayTips = { responseDelayTime, responseDelay }
    const options = { modelApi, apiKey, model: AiModelName, roleSetting }
    if (isRoom && room && content.replace(`${botName}`, '').trimStart() && isPrefix) {
      let question = (await msg.mentionText()) || content.replace(`${botName}`, '') // 去掉艾特的消息主体
      // 群聊消息去掉艾特主体后，匹配自动回复前缀数组中的任意一个前缀
      isPrefix && (question = question.replace(new RegExp(`^(${autoReplyPrefix.join('|')})`), ''))
      await aiReply(question, { chatId, contact: room, room, ...delayTips }, options)
    } else if (isAlias && !room && isPrefix) {
      let question = content
      // 私人聊天直接匹配自动回复前缀数组中的任意一个前缀
      question = question = question.replace(new RegExp(`^(${autoReplyPrefix.join('|')})`), '')
      await aiReply(question, { chatId, contact, room: null, ...delayTips }, options)
    } else {
      // 其他情况不处理
      return
    }
  } catch (e) {
    log.error('msgReply:', e)
  }
}

/**
 * @Author: lcq
 * @Date: 2025-01-01 15:02:18
 * @brief: AI回复
 * @param {*} question
 * @param {*} contact
 * @param {*} room
 * @param {*} autoReply
 * @param {*} modelApi
 * @param {*} apiKey
 * @return {*}
 */
async function aiReply(
  question,
  { chatId, contact, room, responseDelayTime, responseDelay },
  { modelApi, apiKey, model, roleSetting }
) {
  log.info('🌸🌸🌸 / question: ', question)
  const errMsg = '我好像出了点问题，等会再试试吧'
  let replyContent = errMsg
  let thinkTimeout = null
  if (responseDelayTime > 0) {
    thinkTimeout = setTimeout(() => {
      const think = responseDelay || '我在思考中...'
      contact.say(think)
      replyToView(bot, room, think)
    }, responseDelayTime * 1000)
  }

  const say = (errTip = '') => {
    thinkTimeout && clearTimeout(thinkTimeout)
    contact.say(errTip || replyContent)
    log.info('🌸🌸🌸 / replyContent: ', replyContent)
    replyToView(bot, room, replyContent)
  }

  const aiPlatform = await ai.loadModel(modelApi).catch((err) => {
    log.error('aiModel:', JSON.stringify(err))
    replyContent = err?.message || replyContent
    say(errMsg)
  })

  aiPlatform &&
    aiPlatform(question, chatId, { apiKey, model, roleSetting })
      .then((response) => {
        replyContent = response
        say()
      })
      .catch((err) => {
        replyContent = err?.message || replyContent
        log.error('aiModel:', JSON.stringify(err))
        say(errMsg)
      })
}

/**
 * @Author: lcq
 * @Date: 2025-01-01 14:57:14
 * @brief: 回复消息到前端
 * @param {*} bot
 * @param {*} room
 * @param {*} replyContent
 * @return {*}
 */
function replyToView(bot, room, replyContent) {
  createSelfMessageDetail(bot, room, replyContent)
    .then((res) => {
      res?.message?.text &&
        sendMessageToWeb({
          cmd: 'bot-message',
          data: responseJson(res)
        })
    })
    .catch((err) => {
      log.error('createSelfMessageDetail:', err)
    })
}

// 分片长度
const SINGLE_MESSAGE_MAX_SIZE = 500

/**
 * 发送
 * @param talker 发送哪个  room为群聊类 text为单人
 * @param msg
 * @returns {Promise<void>}
 */
// eslint-disable-next-line no-unused-vars
async function trySay(talker, msg) {
  const messages = []
  let message = msg
  while (message.length > SINGLE_MESSAGE_MAX_SIZE) {
    messages.push(message.slice(0, SINGLE_MESSAGE_MAX_SIZE))
    message = message.slice(SINGLE_MESSAGE_MAX_SIZE)
  }
  messages.push(message)
  for (const msg of messages) {
    await talker.say(msg)
  }
}

/**
 * 分组消息
 * @param text
 * @returns {Promise<*>}
 */
// eslint-disable-next-line no-unused-vars
async function splitMessage(text) {
  let realText = text
  const item = text.split('- - - - - - - - - - - - - - -')
  if (item.length > 1) {
    realText = item[item.length - 1]
  }
  return realText
}
